package io.github.wslxm.springbootplus2.manage.login.service.impl;

import io.github.wslxm.springbootplus2.client.sys.model.vo.USysConfigVO;
import io.github.wslxm.springbootplus2.constant.ConfigKey;
import io.github.wslxm.springbootplus2.core.config.error.ErrorException;
import io.github.wslxm.springbootplus2.core.utils.validated.XjValidUtil;
import io.github.wslxm.springbootplus2.manage.login.model.dto.LoginDTO;
import io.github.wslxm.springbootplus2.manage.login.service.LoginHandler;
import io.github.wslxm.springbootplus2.manage.login.service.LoginService;
import io.github.wslxm.springbootplus2.manage.login.strategy.context.LoginChannelContext;
import io.github.wslxm.springbootplus2.manage.login.strategy.service.LoginStrategy;
import io.github.wslxm.springbootplus2.manage.sys.model.entity.SysUser;
import io.github.wslxm.springbootplus2.manage.sys.service.SysConfigService;
import io.github.wslxm.springbootplus2.manage.sys.service.SysUserService;
import io.github.wslxm.springbootplus2.utils.JwtUtil;
import io.github.wslxm.springbootplus2.utils.model.JwtUser;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;

/**
 * 登录实现逻辑
 * @author wangsong
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysConfigService configService;

    @Autowired
    private HttpServletResponse response;

    /**
     * 登录渠道
     */
    @Autowired
    private LoginChannelContext loginChannelContext;

    /**
     * 自定义验证 (子模块自定义更多登录验证)
     */
    private final LoginHandler validator;

    @Autowired
    public LoginServiceImpl(@Autowired(required = false) LoginHandler validator) {
        this.validator = validator;
    }

    @Override
    public boolean login(LoginDTO dto) {
        XjValidUtil.isBlank(dto.getChannel(), "login.channel.NotBlank");
        LoginStrategy channel = loginChannelContext.getChannel(dto.getChannel());
        XjValidUtil.isNull(channel, "login.channel.NotNull");
        // 获取要登录的用户
        SysUser user = channel.getSysUser(dto);
        // 登录验证
        if (validator != null) {
            validator.validate(dto,user);
        }
        try {
            channel.login(dto, user);
        } catch (ErrorException e) {
            // 登录失败
            if (validator != null) {
                validator.fail(dto,user, e);
            }
            throw e;
        }
        // 登录成功
        if (validator != null) {
            validator.success(dto,user);
        }
        USysConfigVO xjConfig = configService.findByCode(ConfigKey.MANAGE_LOGIN_EXPIRATION);
        Integer expiration = xjConfig != null ? Integer.parseInt(xjConfig.getContent()) : 60;
        // 5、生成jwt
        JwtUser jwtUser = new JwtUser();
        jwtUser.setUserId(user.getId());
        jwtUser.setFullName(user.getFullName());
        jwtUser.setType(JwtUtil.userType[0]);
        // 设置token有效期(分)
        jwtUser.setExpiration(expiration);
        JwtUtil.createToken(jwtUser, response);

        // 6、刷新最后登录时间
        SysUser updUser = new SysUser();
        updUser.setId(user.getId());
        updUser.setEndTime(LocalDateTime.now());
        return sysUserService.updateById(updUser);
    }
}
